package per.turtle.file.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.MinioException;
import lombok.RequiredArgsConstructor;
import okhttp3.Response;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import per.turtle.common.core.utils.file.MimeTypeUtils;
import per.turtle.file.config.MinioConfig;
import per.turtle.file.service.ISysFileService;
import per.turtle.file.utils.FileUploadUtils;
import per.turtle.system.dto.SysFile;

import java.io.FileNotFoundException;
import java.time.LocalDateTime;

/**
 * Minio 文件存储
 *
 * @author turtle
 */
@Primary
@RequiredArgsConstructor
@Service
public class MinioSysFileServiceImpl implements ISysFileService {

    private final MinioConfig minioConfig;

    private final MinioClient client;

    @Override
    public GetObjectResponse downloadFile(SysFile file) throws FileNotFoundException, MinioException {
        GetObjectArgs args = GetObjectArgs.builder().bucket(file.getBucketName()).object(StrUtil.format("{}/{}", file.getPath(), file.getName())).build();
        try {
            return client.getObject(args);
        } catch (ErrorResponseException e) {
            Response res = e.response();
            if (res.code() == HttpStatus.HTTP_NOT_FOUND) {
                throw new FileNotFoundException("未找到该文件！");
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new MinioException();
        }
    }

    @Override
    public SysFile uploadFile(MultipartFile file, String bucketName) throws Exception {
        // 校验文件
        FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);

        // 上传文件
        String path = DateUtil.format(LocalDateTime.now(), "yyyy/MM/dd");
        String fileName = IdUtil.fastUUID() + StrPool.DOT + FileUploadUtils.getExtension(file);
        PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(StrUtil.format("{}/{}", path, fileName))
                                          .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
        client.putObject(args);

        // 返回文件信息
        SysFile sysFile = new SysFile();
        sysFile.setBucketName(bucketName);
        sysFile.setPath(path);
        sysFile.setName(fileName);
        sysFile.setUrl(StrUtil.format("{}/{}/{}/{}", minioConfig.getUrl(), bucketName, path, fileName));
        return sysFile;
    }

}
